<?php
/**
 * @author dinglin
 * 每日0：00后开始执行，且只执行一次
 * 为每位员工创建当日初始记录
 * 会同步今日的请假，出差，公出记录. 有撤销和驳回的也会统计在初始状态
 * 如果同一时间段既有请假，也有出差或公出，只会log异常
 * */
apf_require_class('Oa_Job_Attendance_Abstract');
apf_require_class('Const_LeaveType');
class Oa_Job_Attendance_InitUsersDayStatus extends Oa_Job_Attendance_Abstract {

    /** 考勤系统读 **/
    private $readdb = "attendance_slave";
    /** 考勤系统写 **/
    private $writedb = "attendance_master";
    //
    private $day = 28;
    //今天
    private $date = '';
    //sql
    private $sql = '';
    //上班时间
    private $am_start_work = 900;
    private $am_end_record = 930;
    private $am_end_work = 1200;
    private $pm_start_work = 1400;
    private $pm_end_record = 1430;
    private $pm_end_work = 1800;

    public function run($date){
        if($date){
            $this->date = $date;
        }else{
            $this->date = date('Ymd');
        }

        $this->log("开始{$this->date}日初始化员工工作状态日志数据...");

        //取出所有在职员工数据
        $all_users = $this->_get_all_users_on();

        //取出今日的请假，公出，出差记录
        $all_users_status_today = $this->_get_all_users_status_today();
        //去掉公出
        $this->_remove_work_out($all_users_status_today);
        //已经存在过滤
        $exit_users = $this->_get_all_user_day_record();
        //数据处理，到user_day_status
        foreach($all_users as $user){

            if(!empty($exit_users) && in_array($user['user_id'], $exit_users)){
                continue;
            }

            $holiday_u_status = null;
            $bstrip_u_status = null;
            $insert_data = array();

            if(isset($all_users_status_today['holiday'][$user['user_id']])){
                $holiday_u_status = $all_users_status_today['holiday'][$user['user_id']];
            }
            if(isset($all_users_status_today['bstrip'][$user['user_id']])){
                $bstrip_u_status = $all_users_status_today['bstrip'][$user['user_id']];
            }
            $insert_data['user_id'] = $user['user_id'];
            $insert_data['dateline'] = $this->date;

            if( !empty($holiday_u_status) && !empty($bstrip_u_status) ){
                //同一天内既有请假，又有公出，出差
                $this->_do_holiday_and_bstrip_record( $holiday_u_status ,$bstrip_u_status,$insert_data);

            }elseif( !empty($holiday_u_status) ){
                //请假
                $this->_do_holiday_record( $holiday_u_status , $insert_data );

            }elseif( !empty($bstrip_u_status) ){
                //公出，出差
                $this->_do_bstrip_record($bstrip_u_status, $insert_data);
            }
            //插入数据
            $this->_insert_user_day_status($insert_data);
        }
        unset($all_users);
        unset($all_users_status_today);
        $this->log("员工工作状态初始化完毕");
    }
    /**
     * 获取所有用户初始打卡记录
     * @return multitype:
     */
    private function _get_all_user_day_record(){
        $result = array();
        $this->sql = "SELECT user_id FROM user_day_status WHERE dateline={$this->date}";
        $users = $this->get_db_rows($this->sql,$this->writedb,array());
        foreach($users as $one){
            $result[$one['user_id']] = $one['user_id'];
        }
        return $result;
    }
    /**
     * 插入员工到初始记录
     * @param unknown_type $insert_data
     */
    private function _insert_user_day_status($data){

        if(isset($data['error']) && $data['error']){
            return;
        }

        $this->sql = "INSERT INTO user_day_status (user_id,dateline,days,am_status,am_type,am_leave_status,pm_status,pm_type,pm_leave_status,is_later,leave_early) values (%s)";
        //以下准备数据
        $insert_data = array(
                'user_id'        => $data['user_id'],
                'dateline'       => $data['dateline'],
                'days'           => isset( $data['days'] ) ? $data['days'] : 0.0,
                'am_status'      => isset( $data['am_status'] ) ? $data['am_status'] : Const_LeaveType::KQ_AM_STATUS_5,
                'am_type'        => isset( $data['am_type'] ) ? $data['am_type'] : 0,
                'am_leave_status'=> isset( $data['am_leave_status'] ) ? $data['am_leave_status'] : 0,
                'pm_status'      => isset( $data['pm_status'] ) ? $data['pm_status'] : Const_LeaveType::KQ_PM_STATUS_6,
                'pm_type'        => isset( $data['pm_type'] ) ? $data['pm_type'] : 0,
                'pm_leave_status'=> isset( $data['pm_leave_status'] ) ? $data['pm_leave_status'] : 0,
                'is_later'       => 0,
                'leave_early'    => 0,
        );

        $this->sql = sprintf($this->sql,join(',',$insert_data));
        $this->execute( $this->sql,array(), $this->writedb);
        $this->log("初始化date:{$this->date}日的user_id:{$data['user_id']}早上打卡记录完毕");
        unset($insert_data);
        unset($data);
    }
    /**
     * 获取所有在职员工
     * @return multitype:
     */
    private function _get_all_users_on() {
        $this->sql = "SELECT user_id FROM user_info WHERE job_status = '在职'";
        return $this->get_db_rows($this->sql,$this->writedb,array());
    }
    /**
     * 获取所有员工请假，公出，出差记录
     * @return multitype:
     */
    private function _get_all_users_status_today(){
        /** 28号之后*/
/*        if( intval(date('d')) > $this->day ){
            $this->sql = "SELECT user_id,leave_id,leave_type,leave_status FROM user_last_leave_record WHERE dateline={$this->date}";
            $temp = $this->get_db_rows($this->sql,$this->writedb,array());
            $holidays = array();
            $bstrip = array();
            $temp_holiday = array();
            foreach ($temp as $one){
                //如果是出差或公出
                if($one['leave_type'] == Const_LeaveType::LEAVE_TYPE_GONGCHU || $one['leave_type'] == Const_LeaveType::LEAVE_TYPE_CHUCHA ){
                    $bstrip[] = $one;
                }else{//如果是请假,同步成请假数据格式
                    $temp_record = $this->_get_leave_record_by_id($one['leave_id']);
                    $temp_holiday['user_id'] = $one['user_id'];
                    //上午
                    if($temp_record['start_time'] <= $this->am_start_work ){
                        $temp_holiday['am_leave_id']     = $one['leave_id'];
                        $temp_holiday['am_type']         = $one['leave_type'];
                        $temp_holiday['am_leave_status'] = $one['leave_status'];
                    }else{
                        $temp_holiday['am_leave_id']     = 0;
                        $temp_holiday['am_type']         = 0;
                        $temp_holiday['am_leave_status'] = 0;
                    }
                    //下午
                    if($temp_record['end_time'] >= $this->pm_end_work){
                        $temp_holiday['pm_leave_id']     = $one['leave_id'];
                        $temp_holiday['pm_type']         = $one['leave_type'];
                        $temp_holiday['pm_leave_status'] = $one['leave_status'];
                    }else{
                        $temp_holiday['pm_leave_id']     = 0;
                        $temp_holiday['pm_type']         = 0;
                        $temp_holiday['pm_leave_status'] = 0;
                    }
                    $holidays[] = $temp_holiday;
                }
            }
        }else{/** 28号之前 */
            //请假记录
            $this->sql = "SELECT user_id,am_leave_id,am_type,am_leave_status,pm_leave_id,pm_type,pm_leave_status FROM user_leave_record_ext WHERE dateline={$this->date}";
            $holidays = $this->get_db_rows($this->sql,$this->writedb,array());

            //公出、出差记录
            $this->sql = "SELECT user_id,leave_id,leave_type,leave_status,leave_time FROM user_leave_daily WHERE dateline={$this->date}";
            $bstrip = $this->get_db_rows($this->sql,$this->writedb,array());
        //}
        $holidays = $this->_do_data_to_index_id($holidays);
        $bstrip = $this->_do_data_to_index_id($bstrip);
        $result = array(
            'holiday'=>$holidays,
            'bstrip'=>$bstrip
        );
        unset($holidays);
        unset($bstrip);
        return $result;
    }
    /**
     * 数据转换为以user_id为索引
     * @param unknown_type $data
     * @return multitype:unknown
     */
    private function _do_data_to_index_id($data){
        $result = array();
        foreach($data as $one){
            $result[$one['user_id']] = $one;
        }
        unset($data);
        return $result;
    }
    /**
     * 根据id查询一条公出数据
     * @param unknown_type $id
     * @return array
     */
    private function _get_leave_record_by_id($id)
    {
        $this->sql = "SELECT start_time,end_time FROM leave_record WHERE id=".$id;
        $leave_record = $this->get_db_row($this->sql,$this->writedb,array());
        if(!empty($leave_record))
        {
            $start_time = intval(date('Hi',strtotime($leave_record['start_time'])));
            $leave_date = intval(date('Ymd',strtotime($leave_record['end_time'])));
            $end_time = $this->pm_end_work;
            if( $leave_date == $this->date){
                $end_time = intval(date('Hi',strtotime($leave_record['end_time'])));
            }
            $leave_record['start_time'] = $start_time;
            $leave_record['end_time'] = $end_time;
        }
        return $leave_record;
    }
    /**
     * 处理请假数据
     * @param unknown_type $holiday_u_status
     * @param unknown_type $insert_data
     */
    private function _do_holiday_record($holiday_u_status,&$insert_data){
        $days = 0;
        if($holiday_u_status['am_leave_id'] && $holiday_u_status['pm_leave_id']){
            $days = 1;
        }elseif($holiday_u_status['am_leave_id'] || $holiday_u_status['pm_leave_id']){
            $days = 0.5;
        }
        $insert_data['days'] = $days;
        $insert_data['am_type'] = $holiday_u_status['am_type'];
        $insert_data['am_leave_status'] = $holiday_u_status['am_leave_status'];
        $insert_data['pm_type'] = $holiday_u_status['pm_type'];
        $insert_data['pm_leave_status'] = $holiday_u_status['pm_leave_status'];
        unset($holiday_u_status);
    }
    /**
     * 处理公出，出差数据
     * @param unknown_type $bstrip_u_status
     * @param unknown_type $insert_data
     */
    private function _do_bstrip_record($bstrip_u_status,&$insert_data){
        $insert_data['days'] = $bstrip_u_status['leave_time'];
        //取出详细数据
        $leave_record = $this->_get_leave_record_by_id($bstrip_u_status['leave_id']);
        //上午时间段公出,出差
        if( $leave_record['start_time'] <= $this->am_start_work && $leave_record['end_time'] >= $this->am_end_record){
            $insert_data['am_type'] = $bstrip_u_status['leave_type'];
            $insert_data['am_leave_status'] = $bstrip_u_status['leave_status'];
        }
        //下午时间段公出
        if( $leave_record['start_time'] <= $this->pm_start_work && $leave_record['end_time'] >= $this->pm_end_record){
            $insert_data['pm_type'] = $bstrip_u_status['leave_type'];
            $insert_data['pm_leave_status'] = $bstrip_u_status['leave_status'];
        }
        unset($bstrip_u_status);
    }
    /**
     * 处理同一天内既有请假，又有公出，出差
     * @param unknown_type $holiday_u_status
     * @param unknown_type $bstrip_u_status
     * @param unknown_type $insert_data
     */
    private function _do_holiday_and_bstrip_record($holiday_u_status,$bstrip_u_status,&$insert_data){
        //时间重复异常
        if( $holiday_u_status['am_leave_id'] && $holiday_u_status['pm_leave_id'] ){
            $this->log("{$this->date}日的用户(ID".$insert_data['user_id'].')请假与出差或公出时间冲突异常！');
            $insert_data['error']=true;
            unset($bstrip_u_status);
            return 0;
        }
        //取出详细数据
        $leave_record = $this->_get_leave_record_by_id($bstrip_u_status['leave_id']);
        //上午请假
        if( $holiday_u_status['am_leave_id'] && $leave_record['start_time'] <= $this->am_end_work){
            $this->log("{$this->date}日的用户(ID".$insert_data['user_id'].')上午请假与出差或公出时间冲突异常！');
            $insert_data['error']=true;
            unset($bstrip_u_status);
            return 0;
        }elseif( $holiday_u_status['am_leave_id'] ){
            $insert_data['am_type'] = $holiday_u_status['am_type'];
            $insert_data['am_leave_status'] = $holiday_u_status['am_leave_status'];
            //下午时间段公出
            if( $leave_record['start_time'] <= $this->pm_start_work && $leave_record['end_time'] >= $this->pm_end_record){
                $insert_data['pm_type'] = $bstrip_u_status['leave_type'];
                $insert_data['pm_leave_status'] = $bstrip_u_status['leave_status'];
            }
        }
        //下午请假
        if( $holiday_u_status['pm_leave_id'] && $leave_record['end_time'] >= $this->pm_start_work ){
            $this->log("{$this->date}日的用户(ID".$insert_data['user_id'].')下午请假与出差或公出时间冲突异常！');
            $insert_data['error']=true;
            unset($holiday_u_status);
            return 0;
        }elseif($holiday_u_status['pm_leave_id']){
            //上午时间段公出,出差
            if( $leave_record['start_time'] <= $this->am_start_work && $leave_record['end_time'] >= $this->am_end_record){
                $insert_data['am_type'] = $bstrip_u_status['leave_type'];
                $insert_data['am_leave_status'] = $bstrip_u_status['leave_status'];
            }
            $insert_data['pm_type'] = $holiday_u_status['pm_type'];
            $insert_data['pm_leave_status'] = $holiday_u_status['pm_leave_status'];
        }
        $insert_data['days'] = 1;
        unset($holiday_u_status);
        unset($bstrip_u_status);
    }
    /**
     * 去掉公出记录
     */
    private function _remove_work_out(&$data){
        $this->_remove_work_out_1($data['holiday']);
        $this->_remove_work_out_2($data['bstrip']);
    }
    /**
     * 去掉公出记录
     * @param unknown_type $data
     */
    private function _remove_work_out_1(&$data){
        foreach($data as $index => $value){
            if($value['am_type'] == Const_LeaveType::LEAVE_TYPE_GONGCHU){
                $data[$index]['am_type'] = 0 ;
                $data[$index]['am_leave_id'] = 0 ;
                $data[$index]['am_leave_status'] = 0 ;
            }
            if($value['pm_type'] == Const_LeaveType::LEAVE_TYPE_GONGCHU){
                $data[$index]['pm_type'] = 0 ;
                $data[$index]['pm_leave_id'] = 0 ;
                $data[$index]['pm_leave_status'] = 0 ;
            }
        }
    }
    /**
     * 去掉公出记录
     */
    private function _remove_work_out_2(&$data){
        foreach($data as $index => $value){
            if($value['leave_type'] == Const_LeaveType::LEAVE_TYPE_GONGCHU){
                unset($data[$index]);
            }
        }
    }
}